package com.cg.design.depthdesign.singleton;

/**
 * 采用延迟加载的线程安全单例
 * <p>
 * 为了解决这个问题， 你必须在创建首个单例对象时对线程进行同步。
 *
 * @author cg
 * @program LeetCode->MultiLazySingleton
 * @create 2022-07-18 22:04
 **/
public class MultiLazySingleton {

    // The field must be declared volatile so that double check lock would work
    // correctly.
    private static volatile MultiLazySingleton instance;

    public String value;

    private MultiLazySingleton(String value) {
        this.value = value;
    }

    public static MultiLazySingleton getInstance(String value) {
        // The approach taken here is called double-checked locking (DCL). It
        // exists to prevent race condition between multiple threads that may
        // attempt to get singleton instance at the same time, creating separate
        // instances as a result.
        //
        // It may seem that having the `result` variable here is completely
        // pointless. There is, however, a very important caveat when
        // implementing double-checked locking in Java, which is solved by
        // introducing this local variable.
        //
        // You can read more info DCL issues in Java here:
        // https://refactoring.guru/java-dcl-issue
        MultiLazySingleton result = instance;
        if (result != null) {
            return result;
        }
        synchronized (Singleton.class) {
            if (instance == null) {
                instance = new MultiLazySingleton(value);
            }
            return instance;
        }
    }

}
